#include <string.h>
#include "ctl_hand_msg.h"
#include "../thirdparty/cJSON/cJSON.h"
#include "../config.h"
//{"user":1,"device_number":DEVICE_ALL_WHEELS,"cmd":TURN_LEFT,"hands_data":
//[
//{"motor":1,"postion":1500,"speed":123,"time":500},
//{"motor":2,"postion":1500,"speed":123,"time":500}
//]		
static char* CTL_HAND_GROUP_MSG = "{\"user\":%d,\"cmd\":%d,\"scene_code\":%d,\"array_code\":%d,\"speed\":%d,\"start_code\":%d,\"loop\":%d}";
static char* CTL_HAND_MSG = "{\"user\":%d,\"cmd\":%d,\"hands_data\":[{\"motor\":%d,\"postion\":%d,\"speed\":%d,\"time\":%d}]}";
static char* CTL_HANDS_MSG = "{\"user\":%d,\"cmd\":%d,\"hands_data\":[{\"motor\":%d,\"postion\":%d,\"speed\":%d,\"time\":%d}";//]}";
static char* CTL_HAND_DATA_MSG = ",{\"motor\":%d,\"postion\":%d,\"speed\":%d,\"time\":%d}";


ctl_hand_msg* create_ctl_hand_msg(char msgtype,int user_id,int cmd,int motion_size,motion_data* motion_datas_,motion_group_data * group_data_)
{
	ctl_hand_msg * msg = (ctl_hand_msg*) robot_malloc(sizeof(ctl_hand_msg),true);
	if(!cmd)
	{
		dbg_info("create_ctl_hand_msg:error param");
		return NULL;
	}
	msg->msg_ = robot_malloc(sizeof(msg_base),true);
	msg->msg_->data = robot_malloc(MSG_MAX_LEN*sizeof(char),true);
	msg->msg_->type = msgtype;
	msg->user_id = user_id;
	msg->cmd =  cmd;

	if(motion_size >0){
		msg->motion_size =  motion_size;
		msg->motion_datas_  = (motion_data*) robot_malloc(motion_size*sizeof(motion_data),true);
		memcpy(msg->motion_datas_  ,motion_datas_,motion_size * sizeof(motion_data));
	}
	if(group_data_){
		msg->group_data_ = (motion_group_data*) robot_malloc(sizeof(motion_group_data),true);
		memcpy(msg->group_data_  ,group_data_,sizeof(motion_group_data));
	}
	return msg;
}

int distory_ctl_hand_msg(ctl_hand_msg * msg)
{
	if(!msg)
	{
		dbg_info("distory_ctl_hand_msg:error param");
		return MSG_ERROR_NULL_MSG;
	}
	if(msg->msg_) {
 		if(msg->msg_->data){
			free(msg->msg_->data);
			msg->msg_->data = NULL;
		}
		free(msg->msg_);
		msg->msg_ = NULL;
	}
	if(msg->motion_datas_) {
		free(msg->motion_datas_);
		msg->motion_datas_ = NULL;
	}
	if(msg->group_data_){
		free(msg->group_data_);
		msg->group_data_ = NULL;
	}
	free(msg);
	return 0;
}

int serialize_ctl_hand_msg(ctl_hand_msg * msg,char** out_msg,int* out_len)
{
	char* data;
	int i = 0,ret = 0;
	if(!msg){
		dbg_info("serialize_ctlhand_msg:null msg!");
		return MSG_ERROR_NULL_MSG;
	}
	if(!msg->msg_){
		dbg_info("serialize_ctlhand_msg error: null base message!");
		return MSG_ERROR_NULL_MSG;
	}

	if(!msg->motion_datas_ && !msg->group_data_){
		dbg_info("serialize_ctlhand_msg error: no action data!");
		return MSG_ERROR_NULL_MSG;	
	}
	data = msg->msg_->data;
	if(msg->cmd == CTL_CAR_CMD_CTL_MOTION && msg->motion_size>0){//执行单个动作
		if(msg->motion_size==1){
			msg->msg_->len = sprintf(data,CTL_HAND_MSG,msg->user_id,msg->cmd,
							msg->motion_datas_->motor,msg->motion_datas_->postion,
							msg->motion_datas_->speed,msg->motion_datas_->time);
			dbg_info("serialize_ctlhand_msg_1:%s,len:%d",data,msg->msg_->len);
		}else{
			sprintf(data,CTL_HANDS_MSG,msg->user_id,msg->cmd,
								msg->motion_datas_->motor,msg->motion_datas_->postion,
								msg->motion_datas_->speed,msg->motion_datas_->time);
			i=1;
			while(i<msg->motion_size)
			{	
				char templet[MSG_MAX_LEN-MSG_HEAD_LEN]={0};
				sprintf(templet,CTL_HAND_DATA_MSG,
								(msg->motion_datas_+i)->motor,(msg->motion_datas_+i)->postion,
								(msg->motion_datas_+i)->speed,(msg->motion_datas_+i)->time);
				strcat(data,templet);
				i++;
			}
			strcat(data,"]}");
			dbg_info("serialize_ctlhand_msg_1:%s,len:%d",data,msg->msg_->len);
			msg->msg_->len = strlen(data);
		}
	}
	else if(msg->cmd == CTL_CAR_CMD_CTL_MOTION_GROUP){//执行动作组
		msg->msg_->len = sprintf(data,CTL_HAND_GROUP_MSG,msg->user_id,msg->cmd,
							msg->group_data_->scene_code,msg->group_data_->array_code,
							msg->group_data_->speed,msg->group_data_->start_code,msg->group_data_->loop);
			dbg_info("serialize_ctlhand_group msg_1:%s,len:%d",data,msg->msg_->len);
	}

	ret =  serialize_msg(msg->msg_ , out_msg , out_len);
	return ret;
}

/*

*/
int deserialize_ctl_hand_msg(char * msg,int len,ctl_hand_msg** out_msg)
{
	int ret = 0,i = 0;
	cJSON *jsonroot;
	cJSON *hands_data;
	if(!msg||len<=0){
		dbg_info("deserialize_ctlcar_msg:null msg");
		return MSG_ERROR_NULL_MSG;
	}
	ctl_hand_msg* car_msg = (ctl_hand_msg*)robot_malloc(sizeof(ctl_hand_msg),true);
	ret = deserialize_msg(msg,len,&(car_msg->msg_));
	if(ret){
		dbg_info("deserialize_ctlcar_msg=>deserialize_msg error ret:%d",ret);
		return ret;
	}
	jsonroot = cJSON_Parse(car_msg->msg_->data); 
	car_msg->user_id = cJSON_GetObjectItem(jsonroot,"user")->valueint;
	car_msg->cmd = cJSON_GetObjectItem(jsonroot,"cmd")->valueint;
	if(car_msg->cmd == CTL_CAR_CMD_CTL_MOTION){
		hands_data = cJSON_GetObjectItem(jsonroot,"hands_data");
		if(hands_data){
			cJSON *handlist=hands_data->child;//子对象
			motion_data* motion_datas_ =  NULL;
			car_msg->motion_size = cJSON_GetArraySize(hands_data);
			motion_datas_ = (motion_data*)robot_malloc((car_msg->motion_size)*sizeof(motion_data),true);
			
			while(handlist!=NULL && i < car_msg->motion_size)
			{
				(motion_datas_+i)->motor = cJSON_GetObjectItem(handlist,"motor")->valueint;
				(motion_datas_+i)->postion = cJSON_GetObjectItem(handlist,"postion")->valueint;
				(motion_datas_+i)->speed = cJSON_GetObjectItem(handlist,"speed")->valueint;
				(motion_datas_+i)->time = cJSON_GetObjectItem(handlist,"time")->valueint;
				handlist=handlist->next;
				i++;
			}
			car_msg->motion_datas_ = motion_datas_;
		}else{
			dbg_info("deserialize_ctlcar_msg=>get ctl car motion cmd but hands data is null error!");
		}
	}else if(car_msg->cmd == CTL_CAR_CMD_CTL_MOTION_GROUP){
		//"{\"user\":%d,\"cmd\":%d,\"scene_code\":%d,\"array_code\":%d,\"speed\":%d,\"start_code\":%d,\"loop\":%d}";
		motion_group_data* group_data_ = (motion_group_data*)robot_malloc(sizeof(motion_group_data),true);
		group_data_->scene_code = cJSON_GetObjectItem(jsonroot,"scene_code")->valueint;
		group_data_->array_code = cJSON_GetObjectItem(jsonroot,"array_code")->valueint;
		group_data_->speed		= cJSON_GetObjectItem(jsonroot,"speed")->valueint;
		group_data_->start_code = cJSON_GetObjectItem(jsonroot,"start_code")->valueint;
		group_data_->loop		= cJSON_GetObjectItem(jsonroot,"loop")->valueint;
		car_msg->group_data_ = group_data_;
	}
	if(jsonroot)
		cJSON_Delete(jsonroot);
	*out_msg = car_msg;
	return 0;
}
